#ifndef EMPLOYEE__
#define EMPLOYEE__

#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketStream.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Exception.h"
#include "Poco/Thread.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "../include/Job.h"
#include "../include/Encoder.h"
#include "../include/ConnectionHandler.h"


// The Employee class, implements the Photo Hut employee. The Employee connects to the Work Manager server, asks him for a new job,
// downloads the photo relevant to the job, processes the photo according to the requested effects, and uploads the final photo back to the Work Manager.
class Employee
{
private:
	ConnectionHandler* conHandler; // The employee's connection handler.
	int resource, contentLength;
	Mat currentImg; // The photo the employee is currently working on.
	string contentType, xml;

public:
	const short port_;
	const std::string host_;

	// Class Constructor.
	// Parameters: host - the relevant server's address, port - the connection port.
	Employee(std::string host, short port);

	// Class Destructor.
	virtual ~Employee(void);

	// Close down the connection properly.
	void close();

	// Connect to the remote machine
	// Returns false if it was unable to properly connect.
	bool connect();

	// Reconnect to the remote machine
	// Returns false if it was unable to properly connect.
	bool reconnect();

	// Asks the server if there's a new job to work on and downloads it if so.
	// Returns false if the connection failed during process.
	bool getNewJob();

	// Downloads the given job's image.
	// Returns false if the connection failed during process.
	bool getImg(Job& job);

	// Uploads the given job's image to the server.
	// Returns false if the connection failed during process.
	bool sendImg(Job& job);

	// Read one line from the server's reply and put it in a string.
	// Returns false in case connection closed before a newline can be read.
	bool getOneLine(string& answer);

	// Converts the given message from UTF-8 encoding to Ascii.
	void utf8ToAscii (string& toEncode);

	// Converts the given message from Ascii encoding to UTF-8.
	void asciiToUtf8 (string& message);

	// Read a fixed number of bytes from the server - blocking.
	// Returns false in case the connection is closed before bytesToRead bytes can be read.
	bool getBytes(char frame[], int bytesToRead);

	// Process the job's requested effects.
	void processJob(Job& job);

	// Send a fixed number of bytes from the client - blocking.
	// Returns false in case the connection is closed before bytesToWrite bytes can be read.
	bool sendBytes(const char frame[], int bytesToWrite);

	// Send message to the remote host.
	// Returns false in case connection is closed before all the data is sent.
	bool send(const std::string& message);

	// Returns the job's xml in string format.
	string getXML();

};

#endif
